/******************************************************************************* * Copyright (c) 2007, 2014 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * Jeanderson Candido <http://jeandersonbc.github.io> - Bug 433603 *******************************************************************************/ package org.eclipse.ui.tests.services; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.concurrent.atomic.AtomicBoolean; import org.eclipse.core.expressions.EvaluationResult; import org.eclipse.core.expressions.Expression; import org.eclipse.core.expressions.ExpressionConverter; import org.eclipse.core.expressions.ExpressionInfo; import org.eclipse.core.expressions.IEvaluationContext; import org.eclipse.core.internal.expressions.TestExpression; import org.eclipse.core.internal.expressions.WithExpression; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.text.TextSelection; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreePath; import org.eclipse.jface.viewers.TreeSelection; import org.eclipse.ui.IPerspectiveDescriptor; import org.eclipse.ui.IPerspectiveRegistry; import org.eclipse.ui.ISources; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.contexts.IContextActivation; import org.eclipse.ui.contexts.IContextService; import org.eclipse.ui.handlers.IHandlerActivation; import org.eclipse.ui.handlers.IHandlerService; import org.eclipse.ui.internal.WorkbenchWindow; import org.eclipse.ui.internal.handlers.HandlerPersistence; import org.eclipse.ui.services.IEvaluationReference; import org.eclipse.ui.services.IEvaluationService; import org.eclipse.ui.services.ISourceProviderService; import org.eclipse.ui.tests.SelectionProviderView; import org.eclipse.ui.tests.commands.ActiveContextExpression; import org.eclipse.ui.tests.harness.util.UITestCase; import org.junit.Assume; import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; /** * @since 3.3 * */ @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class EvaluationServiceTest extends UITestCase { /** * */ private static final String CHECK_HANDLER_ID = "org.eclipse.ui.tests.services.checkHandler"; private static final String CONTEXT_ID1 = "org.eclipse.ui.command.contexts.evaluationService1"; /** * @param testName */ public EvaluationServiceTest(String testName) { super(testName); } private static class MyEval implements IPropertyChangeListener { public volatile int count = 0; public volatile boolean currentValue; @Override public void propertyChange(PropertyChangeEvent event) { count++; if (event.getProperty() == IEvaluationService.RESULT && event.getNewValue() instanceof Boolean) { currentValue = ((Boolean) event.getNewValue()).booleanValue(); } } } public void testBug334524() throws Exception { IPerspectiveRegistry registry = PlatformUI.getWorkbench().getPerspectiveRegistry(); IPerspectiveDescriptor resourecePerspective = registry.findPerspectiveWithId("org.eclipse.ui.resourcePerspective"); IPerspectiveDescriptor javaPerspective = registry.findPerspectiveWithId("org.eclipse.jdt.ui.JavaPerspective"); String viewId = "org.eclipse.ui.tests.SelectionProviderView"; IWorkbenchWindow window = openTestWindow(); IWorkbenchPage activePage = window.getActivePage(); // show view in resource perspective activePage.setPerspective(resourecePerspective); SelectionProviderView view = (SelectionProviderView) activePage.showView(viewId); processEvents(); // show view in java perspective activePage.setPerspective(javaPerspective); activePage.showView(viewId); processEvents(); // now set the selection IStructuredSelection selection = new StructuredSelection(new String("testing selection")); view.setSelection(selection); processEvents(); // switch perspective & check selection activePage.setPerspective(resourecePerspective); processEvents(); IEvaluationService service = window.getService(IEvaluationService.class); Object currentSelection = service.getCurrentState().getVariable(ISources.ACTIVE_CURRENT_SELECTION_NAME); assertEquals(selection, currentSelection); } public void testBasicService() throws Exception { IWorkbenchWindow window = openTestWindow(); waitForJobs(500, 5000); boolean activeShell = forceActive(window.getShell()); Assume.assumeTrue(activeShell); IEvaluationService service = window .getService(IEvaluationService.class); assertNotNull(service); MyEval listener = new MyEval(); IContextActivation context1 = null; IEvaluationReference evalRef = null; IContextService contextService = null; try { contextService = window.getService(IContextService.class); assertFalse(contextService.getActiveContextIds().contains(CONTEXT_ID1)); evalRef = service.addEvaluationListener( new ActiveContextExpression(CONTEXT_ID1, new String[] { ISources.ACTIVE_CONTEXT_NAME }), listener, IEvaluationService.RESULT); assertEquals(1, listener.count); assertFalse(listener.currentValue); context1 = contextService.activateContext(CONTEXT_ID1); processEvents(); waitForJobs(500, 3000); assertTrue(contextService.getActiveContextIds().contains(CONTEXT_ID1)); assertEquals(2, listener.count); assertTrue(listener.currentValue); contextService.deactivateContext(context1); context1 = null; assertFalse(contextService.getActiveContextIds().contains(CONTEXT_ID1)); assertEquals(3, listener.count); assertFalse(listener.currentValue); service.removeEvaluationListener(evalRef); evalRef = null; assertEquals(4, listener.count); context1 = contextService.activateContext(CONTEXT_ID1); processEvents(); waitForJobs(500, 3000); assertTrue(contextService.getActiveContextIds().contains(CONTEXT_ID1)); assertEquals(4, listener.count); assertFalse(listener.currentValue); contextService.deactivateContext(context1); context1 = null; assertFalse(contextService.getActiveContextIds().contains(CONTEXT_ID1)); assertEquals(4, listener.count); assertFalse(listener.currentValue); } finally { if (context1 != null) { contextService.deactivateContext(context1); } if (evalRef != null) { service.removeEvaluationListener(evalRef); } } } public void testTwoEvaluations() throws Exception { IWorkbenchWindow window = openTestWindow(); boolean activeShell = forceActive(window.getShell()); waitForJobs(500, 5000); final AtomicBoolean shellIsActive = new AtomicBoolean(activeShell); Assume.assumeTrue(shellIsActive.get()); IEvaluationService service = window .getService(IEvaluationService.class); assertNotNull(service); MyEval listener1 = new MyEval(); MyEval listener2 = new MyEval(); IContextActivation context1 = null; IEvaluationReference evalRef1 = null; IEvaluationReference evalRef2 = null; IContextService contextService = null; try { contextService = window.getService(IContextService.class); assertFalse(contextService.getActiveContextIds().contains(CONTEXT_ID1)); evalRef1 = service.addEvaluationListener( new ActiveContextExpression(CONTEXT_ID1, new String[] { ISources.ACTIVE_CONTEXT_NAME }), listener1, IEvaluationService.RESULT); assertEquals(1, listener1.count); assertFalse(listener1.currentValue); evalRef2 = service.addEvaluationListener( new ActiveContextExpression(CONTEXT_ID1, new String[] { ISources.ACTIVE_CONTEXT_NAME }), listener2, IEvaluationService.RESULT); assertEquals(1, listener2.count); assertFalse(listener2.currentValue); evalRef2.setResult(true); context1 = contextService.activateContext(CONTEXT_ID1); processEvents(); waitForJobs(500, 3000); assertTrue(contextService.getActiveContextIds().contains(CONTEXT_ID1)); int count = 0; while (count < 5 && listener1.count != 2) { count++; waitForJobs(100 * count, 1000); } assertEquals(2, listener1.count); assertTrue(listener1.currentValue); // we already set this guy to true, he should skip assertEquals(1, listener2.count); assertFalse(listener2.currentValue); evalRef1.setResult(false); contextService.deactivateContext(context1); processEvents(); waitForJobs(500, 3000); assertFalse(contextService.getActiveContextIds().contains(CONTEXT_ID1)); context1 = null; assertEquals(2, listener2.count); assertFalse(listener2.currentValue); // we already set this guy to false, so he should be the old // values assertEquals(2, listener1.count); assertTrue(listener1.currentValue); } finally { if (context1 != null) { contextService.deactivateContext(context1); } if (evalRef1 != null) { service.removeEvaluationListener(evalRef1); } if (evalRef2 != null) { service.removeEvaluationListener(evalRef2); } } } // TODO fix testRestriction public void TODOtestRestriction() { IWorkbenchWindow window = openTestWindow(); IEvaluationService evaluationService = window .getService(IEvaluationService.class); assertNotNull(evaluationService); IContextService contextService = window .getService(IContextService.class); assertNotNull(contextService); Expression expression = new ActiveContextExpression(CONTEXT_ID1, new String[] { ISources.ACTIVE_CONTEXT_NAME }); final boolean[] propertyChanged = new boolean[1]; final boolean[] propertyShouldChange = new boolean[1]; IPropertyChangeListener propertyChangeListener = new IPropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent event) { if (event.getProperty().equals("foo")) { propertyChanged[0] = true; } } }; IEvaluationReference ref = evaluationService.addEvaluationListener( expression, propertyChangeListener, "foo"); ((WorkbenchWindow)window).getMenuRestrictions().add(ref); IPropertyChangeListener propertyShouldChangeListener = new IPropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent event) { if (event.getProperty().equals("foo")) { propertyShouldChange[0] = true; } } }; evaluationService.addEvaluationListener(expression, propertyShouldChangeListener, "foo"); propertyChanged[0] = false; propertyShouldChange[0] = false; assertFalse(contextService.getActiveContextIds().contains(CONTEXT_ID1)); IContextActivation activation = contextService .activateContext(CONTEXT_ID1); assertTrue(propertyChanged[0]); assertTrue(propertyShouldChange[0]); propertyChanged[0] = false; propertyShouldChange[0] = false; contextService.deactivateContext(activation); assertTrue(propertyChanged[0]); assertTrue(propertyShouldChange[0]); assertFalse(contextService.getActiveContextIds().contains(CONTEXT_ID1)); activation = contextService.activateContext(CONTEXT_ID1); propertyChanged[0] = false; propertyShouldChange[0] = false; assertTrue(contextService.getActiveContextIds().contains(CONTEXT_ID1)); // open second window IWorkbenchWindow window2 = openTestWindow(); assertFalse(propertyChanged[0]); assertTrue(propertyShouldChange[0]); assertFalse(contextService.getActiveContextIds().contains(CONTEXT_ID1)); propertyChanged[0] = false; propertyShouldChange[0] = false; window2.close(); processEvents(); assertTrue(contextService.getActiveContextIds().contains(CONTEXT_ID1)); assertFalse(propertyChanged[0]); assertTrue(propertyShouldChange[0]); } // TODO fix testScopedService public void TODOtestScopedService() throws Exception { IWorkbenchWindow window = openTestWindow(); IEvaluationService service = window .getService(IEvaluationService.class); assertNotNull(service); //assertTrue(service instanceof SlaveEvaluationService); MyEval listener = new MyEval(); IContextActivation context1 = null; IContextService contextService = null; try { service.addEvaluationListener( new ActiveContextExpression(CONTEXT_ID1, new String[] { ISources.ACTIVE_CONTEXT_NAME }), listener, IEvaluationService.RESULT); assertEquals(1, listener.count); assertFalse(listener.currentValue); contextService = window.getWorkbench() .getService(IContextService.class); context1 = contextService.activateContext(CONTEXT_ID1); assertEquals(2, listener.count); assertTrue(listener.currentValue); window.close(); processEvents(); assertEquals(3, listener.count); assertTrue(listener.currentValue); contextService.deactivateContext(context1); context1 = null; assertEquals(3, listener.count); assertTrue(listener.currentValue); } finally { if (context1 != null) { contextService.deactivateContext(context1); } } } private static class UserExpression extends Expression { public String lookFor; public UserExpression(String lookFor) { this.lookFor = lookFor; } @Override public void collectExpressionInfo(ExpressionInfo info) { info.addVariableNameAccess("username"); } @Override public EvaluationResult evaluate(IEvaluationContext context) { String variable = (String) context.getVariable("username"); return lookFor.equals(variable) ? EvaluationResult.TRUE : EvaluationResult.FALSE; } } public void testSourceProvider() throws Exception { IWorkbenchWindow window = openTestWindow(); IEvaluationService service = window .getService(IEvaluationService.class); assertNotNull(service); MyEval listener = new MyEval(); UserExpression expression = new UserExpression("Paul"); IEvaluationReference ref = service.addEvaluationListener(expression, listener, IEvaluationService.RESULT); assertEquals(ISources.ACTIVE_CONTEXT << 1, ref.getSourcePriority()); assertFalse(listener.currentValue); assertEquals(1, listener.count); ISourceProviderService sps = window .getService(ISourceProviderService.class); ActiveUserSourceProvider userProvider = (ActiveUserSourceProvider) sps .getSourceProvider("username"); userProvider.setUsername("John"); assertFalse(listener.currentValue); assertEquals(1, listener.count); userProvider.setUsername("Paul"); assertTrue(listener.currentValue); assertEquals(2, listener.count); userProvider.setUsername("guest"); assertFalse(listener.currentValue); assertEquals(3, listener.count); } public void testSourceProviderPriority() throws Exception { IHandlerService hs = getWorkbench().getService(IHandlerService.class); Collection activations = null; // fill in a set of activations String hsClassName = hs.getClass().getName(); if (hsClassName.equals("org.eclipse.ui.internal.handlers.HandlerService")) { Field hpField = hs.getClass().getDeclaredField("handlerPersistence"); hpField.setAccessible(true); HandlerPersistence hp = (HandlerPersistence) hpField.get(hs); Field activationsField = hp.getClass().getDeclaredField("handlerActivations"); activationsField.setAccessible(true); activations = (Collection) activationsField.get(hp); assertNotNull(activations); } else if (hsClassName.equals("org.eclipse.ui.internal.handlers.LegacyHandlerService")) { Field hsField = hs.getClass().getDeclaredField("LEGACY_H_ID"); String LEGACY_H_ID = (String) hsField.get(null); Field hpField = hs.getClass().getDeclaredField("eclipseContext"); hpField.setAccessible(true); Object eclipseContext = hpField.get(hs); assertNotNull(eclipseContext); Method getMethod = eclipseContext.getClass().getDeclaredMethod("get", new Class[] { String.class }); activations = (Collection) getMethod.invoke(eclipseContext, new Object[] { LEGACY_H_ID + CHECK_HANDLER_ID}); assertNotNull(activations); } else { fail("Incorrect handler service: " + hsClassName); } IHandlerActivation activation = null; Iterator i = activations.iterator(); while (i.hasNext()) { IHandlerActivation ha = (IHandlerActivation) i.next(); if (CHECK_HANDLER_ID.equals(ha.getCommandId())) { activation = ha; } } assertNotNull("Could not find activation for " + CHECK_HANDLER_ID, activation); assertEquals(ISources.ACTIVE_CONTEXT<<1, activation.getSourcePriority()); } public void testPropertyChange() throws Exception { IWorkbenchWindow window = openTestWindow(); IEvaluationService service = window .getService(IEvaluationService.class); assertNotNull(service); MyEval listener = new MyEval(); IExtensionRegistry registry = Platform.getExtensionRegistry(); IConfigurationElement element = null; IConfigurationElement[] elements = registry .getConfigurationElementsFor("org.eclipse.core.expressions.definitions"); for (int i = 0; i < elements.length && element == null; i++) { if (elements[i].getAttribute("id").equals( "org.eclipse.ui.tests.defWithPropertyTester")) { element = elements[i]; } } assertNotNull(element); Expression expr = ExpressionConverter.getDefault().perform(element.getChildren()[0]); service.addEvaluationListener(expr, listener, IEvaluationService.RESULT); assertFalse(listener.currentValue); assertEquals(1, listener.count); StaticVarPropertyTester.result = true; assertFalse(listener.currentValue); assertEquals(1, listener.count); service.requestEvaluation("org.eclipse.ui.tests.class.method"); assertTrue(listener.currentValue); assertEquals(2, listener.count); service.requestEvaluation("org.eclipse.ui.tests.class.method"); assertTrue(listener.currentValue); assertEquals(2, listener.count); } public void testPlatformProperty() throws Exception { IEvaluationService evaluationService = PlatformUI .getWorkbench().getService(IEvaluationService.class); TestExpression test = new TestExpression("org.eclipse.core.runtime", "bundleState", new Object[] { "org.eclipse.core.expressions" }, "ACTIVE", false); WithExpression exp = new WithExpression("org.eclipse.core.runtime.Platform"); exp.add(test); EvaluationResult result= exp.evaluate(evaluationService.getCurrentState()); assertEquals(EvaluationResult.TRUE, result); } public void XtestSystemProperty() throws Exception { // this is not added, as the ability to test system properties with // no '.' seems unhelpful System.setProperty("isHere", "true"); IEvaluationService evaluationService = PlatformUI .getWorkbench().getService(IEvaluationService.class); TestExpression test = new TestExpression("org.eclipse.core.runtime", "isHere", new Object[] { "true" }, null, false); WithExpression exp = new WithExpression( "java.lang.System" ); exp.add(test); EvaluationResult result = exp.evaluate(evaluationService .getCurrentState()); assertEquals(EvaluationResult.TRUE, result); } static class ActivePartIdExpression extends Expression { private String partId; public ActivePartIdExpression(String id) { partId = id; } @Override public void collectExpressionInfo(ExpressionInfo info) { info.addVariableNameAccess(ISources.ACTIVE_PART_ID_NAME); info.addVariableNameAccess(ISources.ACTIVE_CURRENT_SELECTION_NAME); } @Override public EvaluationResult evaluate(IEvaluationContext context){ Object v = context.getVariable(ISources.ACTIVE_PART_ID_NAME); return EvaluationResult.valueOf(partId.equals(v)); } } static class PartSelection { public ISelection selection; public IWorkbenchPart part; public PartSelection(ISelection sel, IWorkbenchPart p) { selection = sel; part = p; } } public void testWorkbenchProvider() throws Exception { IWorkbenchWindow window = openTestWindow(); final IEvaluationService service = window .getWorkbench().getService(IEvaluationService.class); assertNotNull(service); // some setup IWorkbenchPage page = window.getActivePage(); SelectionProviderView view1 = (SelectionProviderView) page .showView(org.eclipse.ui.tests.SelectionProviderView.ID); view1.setSelection(StructuredSelection.EMPTY); SelectionProviderView view2 = (SelectionProviderView) page .showView(org.eclipse.ui.tests.SelectionProviderView.ID_2); TextSelection mySelection = new TextSelection(0, 5); view2.setSelection(mySelection); processEvents(); final ArrayList selection = new ArrayList(); IPropertyChangeListener listener = new IPropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent event) { IEvaluationContext state = service.getCurrentState(); try { ISelection sel = null; IWorkbenchPart part = null; Object o = state .getVariable(ISources.ACTIVE_CURRENT_SELECTION_NAME); if (o instanceof ISelection) { sel = (ISelection) o; } o = state.getVariable(ISources.ACTIVE_PART_NAME); if (o instanceof IWorkbenchPart) { part = (IWorkbenchPart) o; } selection.add(new PartSelection(sel, part)); } catch (Exception e) { e.printStackTrace(); } } }; IEvaluationReference ref = service.addEvaluationListener( new ActivePartIdExpression( org.eclipse.ui.tests.SelectionProviderView.ID), listener, "PROP"); int callIdx = 0; try { // initially ID_2 is showed assertSelection(selection, callIdx, TextSelection.class, SelectionProviderView.ID_2); page.activate(view1); processEvents(); callIdx++; assertSelection(selection, callIdx, StructuredSelection.class, SelectionProviderView.ID); page.activate(view2); processEvents(); callIdx++; assertSelection(selection, callIdx, TextSelection.class, SelectionProviderView.ID_2); assertEquals(window.getActivePage().getActivePart().getSite().getId(), service.getCurrentState().getVariable(ISources.ACTIVE_PART_ID_NAME)); IWorkbenchWindow window2 = openTestWindow(); IWorkbenchPage page2 = window2.getActivePage(); processEvents(); // no change assertEquals(callIdx + 1, selection.size()); SelectionProviderView view3 = (SelectionProviderView) page2 .showView(org.eclipse.ui.tests.SelectionProviderView.ID); processEvents(); // id1 activated with default selection StructuredSelection.EMPTY callIdx++; assertSelection(selection, callIdx, StructuredSelection.class, SelectionProviderView.ID); assertEquals(window2.getActivePage().getActivePart().getSite().getId(), service.getCurrentState().getVariable(ISources.ACTIVE_PART_ID_NAME)); view3.setSelection(new TreeSelection(new TreePath(new Object[] {"nothing"}))); processEvents(); // selection changes, but view id remains the same - so no callIdx increments assertEquals(callIdx + 1, selection.size()); window.getShell().forceActive(); processEvents(); // the shell activate should have forced another change callIdx++; // assertEquals(window.getActivePage().getActivePart().getSite().getId(), // service.getCurrentState().getVariable(ISources.ACTIVE_PART_ID_NAME)); // assertSelection(selection, callIdx, TextSelection.class, SelectionProviderView.ID_2); } finally { service.removeEvaluationListener(ref); } } private void assertSelection(final ArrayList selection, int callIdx, Class clazz, String viewId) { assertEquals(callIdx + 1, selection.size()); assertEquals(clazz, getSelection(selection, callIdx) .getClass()); assertEquals(viewId, getPart(selection, callIdx).getSite().getId()); } private ISelection getSelection(final ArrayList selection, int idx) { return ((PartSelection) selection.get(idx)).selection; } private IWorkbenchPart getPart(final ArrayList selection, int idx) { return ((PartSelection) selection.get(idx)).part; } }